# -*- coding: UTF-8 -*-
import commands
import json
import os
import socket
import thread
import threading
import time
import urlparse

import xml.etree.ElementTree as ET
import yaml

import conf
import http_responser
import log_helper
import lte_response
import power_helper
import z_file
from utils import ip_utils
from utils import ssh_utils
from utils import xml_utils

logger = log_helper.init_logging('lte')

interact_time = 0

g_sock = None
lte_state = None
lte_sniffer_code = None
is_ready = False
location_lock = 2

# 正在重启
is_rebooting = False


def set_status_rebooting(status):
    global is_rebooting
    is_rebooting = status


def get_status_rebooting():
    global is_rebooting
    return is_rebooting


def query_conf(conf_file=None):
    if conf_file is None:
        conf_file = conf.conf_yaml_path
    with open(conf_file, 'r') as f:
        yaml_data_str = f.read()
    all_data = yaml.load(yaml_data_str, Loader=yaml.FullLoader)
    return all_data


def update_conf(content, conf_file=None):
    if conf_file is None:
        conf_file = conf.conf_yaml_path
    with open(conf_file, 'w') as f:
        result = yaml.dump(content)
        result = result.replace("null", "")
        f.write(result)


def send_data(data_str):
    # check_lte_request_timeout()
    logger.info(data_str)
    g_sock.sendto(data_str, (conf.lte_addr, conf.lte_port))


def check_lte_request_timeout():
    count = 0.0
    while not is_ready:
        time.sleep(0.02)
        count += 0.02
        if count > 50.0:
            raise Exception("lte request timeout")


def send_with_response(send_data, suc_code, rule_msg=None):
    # check_lte_request_timeout()
    logger.info(send_data)
    current_time = int(time.time())
    g_sock.sendto(send_data, (conf.lte_addr, conf.lte_port))
    time.sleep(0.5)
    total_time = 0.0
    while total_time < 50.0:
        msg = lte_response.get_msg_by_code_rule_msg(suc_code, rule_msg, current_time)
        if msg:
            return msg
        total_time += 0.2
        time.sleep(0.2)
    raise Exception('lte response timeout')


def get_lte_state():
    return lte_response.get_heart_status()


def set_arcfn(arcfn):
    logger.info('set_arcfn:' + str(arcfn))
    send_data('SetRedirectionInfoExt 0 0 16 ')
    time.sleep(0.5)
    send_data('SetRedirectionInfoExt 1 0 16 0 3 ' + str(arcfn))
    # send_data('SetRedirectionInfo 15 2 0 ' + str(arcfn))


def get_bts_info():
    result = {}
    response_data = send_with_response('GetCellPara', '104')
    xml_str = response_data[response_data.find("<"):]
    tree = ET.XML(xml_str)
    result['band'] = tree.find('band').text.strip()
    result['erfcn'] = tree.find('erfcn').text.strip()
    result['pci'] = tree.find('pci').text.strip()
    # result['mcc'] = tree.find('mcc').text.strip()
    # result['mnc'] = tree.find('mnc').text.strip()
    result['tac'] = tree.find('tac').text.strip()
    result['cellId'] = tree.find('cellId').text.strip()
    mme_data = query_conf()
    result['mcc'] = mme_data['mme']['gummei']['plmn_id']['mcc']
    result['mnc'] = mme_data['mme']['gummei']['plmn_id']['mnc']
    return result


def get_rf_param():
    response_data = send_with_response("GetRfPara", '115', 'GetRfParaRsp')
    result = {'MCC': '', 'MNC': '', 'FCN': '', 'CPI-PSC-BSIC': '', 'LAC-TAC': '', 'cellID': '', 'txPwr': '',
              'listenFcn': ''}
    res_arr = response_data.split(' ')
    start_idx = 3
    if len(res_arr) > 11:
        result['MCC'] = res_arr[start_idx + 1]
        result['MNC'] = res_arr[start_idx + 2]
        result['FCN'] = res_arr[start_idx + 3]
        result['CPI-PSC-BSIC'] = res_arr[start_idx + 4]
        result['LAC-TAC'] = res_arr[start_idx + 5]
        result['cellID'] = res_arr[start_idx + 6]
        result['txPwr'] = res_arr[start_idx + 7]
        result['listenFcn'] = res_arr[start_idx + 8]
    mme_data = query_conf()
    result['MCC'] = mme_data['mme']['gummei']['plmn_id']['mcc']
    result['MNC'] = mme_data['mme']['gummei']['plmn_id']['mnc']
    return result


def set_station_bts_param(mcc, mnc, earfcn, pci, tac, cellid):
    """
    基站参数
    """
    response_data = send_with_response('GetCellPara', '104', 'GetCellParaRsp')
    xml_str = response_data[response_data.find("<"):]
    tree = ET.XML(xml_str)
    tree.find('tac').text = tac
    tree.find('cellId').text = cellid
    tree.find('mcc').text = mcc
    tree.find('mnc').text = mnc
    tree.find('erfcn').text = earfcn
    tree.find('pci').text = pci
    result = " <?xml version='1.0' encoding = 'UTF-8' standalone = 'no' ?>"
    result += ET.tostring(tree, encoding="utf-8").decode("utf-8")
    send_data('SetCellPara ' + result)


def set_bts_info(params):
    old_mcc, old_mnc = get_plmn_id()
    mcc = str(params['plmn'])[:3]
    mnc = str(params['plmn'])[3:]
    earfcn = str(params['earfcn'])
    pci = str(params['pci'])
    tac = str(params['tac'])
    cellid = str(params['cellId'])
    # response_data = send_with_response(
    #     'SetRfPara ' + mcc + ' ' + mnc + ' ' + earfcn + ' ' + pci + ' ' + tac + ' ' + cellid + ' 5 0',
    #     '109', 'SetRfPara')
    set_station_bts_param(mcc, mnc, earfcn, pci, tac, cellid)

    conf_data = query_conf()
    conf_data['mme']['gummei']['plmn_id']['mcc'] = mcc
    conf_data['mme']['tai']['plmn_id']['mcc'] = mcc
    conf_data['mme']['gummei']['plmn_id']['mnc'] = mnc
    conf_data['mme']['tai']['plmn_id']['mnc'] = mnc
    conf_data['mme']['tai']['tac'] = tac
    update_conf(conf_data)
    set_plumn_config(mcc, mnc)
    apn = str(params['apn'])
    ims = str(params.get('ims', ''))
    set_apn_param(apn, ims)
    save_sx_cfg_xml(mcc, mnc, tac)

    if int(old_mcc) != int(mcc) or int(old_mnc) != int(mnc):
        clear_white_black_list()

    return 'success'


def clear_white_black_list():
    for file_path in (conf.white_black_path, conf.user_cfg_path):
        with open(file_path, 'r') as f:
            data_list = f.read().strip().split("\n")
        if len(data_list) > 0:
            with open(file_path, 'w') as f:
                f.write(data_list[0])


def save_sx_cfg_xml(mcc, mnc, tac):
    file_path = conf.sxcfg_xml_path
    tree = xml_utils.read_xml(file_path)
    root = tree.getroot()
    root.find('.//enbInf/enbId/plmn/mcc').text = mcc
    root.find('.//enbInf/enbId/plmn/mnc').text = mnc
    root.find('.//enbInf/tac/item/brdPlmn/item/mcc').text = mcc
    root.find('.//enbInf/tac/item/brdPlmn/item/mnc').text = mnc
    root.find('.//enbInf/tac/item/tac').text = tac
    content = ["<?xml version='1.0' encoding = 'UTF-8' standalone = 'no' ?>", xml_utils.tree_to_string(tree)]
    with open(file_path, 'w') as f:
        f.write("\n".join(content))
    if os.path.exists(file_path):
        ssh_connect = ssh_utils.SSHConnection(
            {"host": conf.REMOTE_HOST, "port": 22, "username": 'root', "pwd": conf.REMOTE_PWD})
        ssh_connect.connect()
        ssh_connect.upload(file_path, '/root/sec/cfg/sxCfg.xml')
        ssh_connect.close()


def set_plumn_config(mcc, mnc):
    """
    pcscf.config
    scscf.config
    smc.config
    """
    for file_path in (conf.pcscf_path, conf.scscf_path, conf.smc_path):
        with open(file_path, 'r') as f:
            data_list = f.read().split("\n")
        new_data_list = []
        for line in data_list:
            if line.startswith("Global-Region-MCC"):
                new_data_list.append('Global-Region-MCC = ' + str(mcc))
            elif line.startswith("Global-Region-MNCS"):
                new_data_list.append('Global-Region-MNCS = ' + str(mnc))
            else:
                new_data_list.append(line)
        with open(file_path, 'w') as f:
            f.write("\n".join(new_data_list))


def set_apn_param(apn, ims):
    """
    1、hss.yaml
    apn: mobile
    2、smf.yaml
    """
    conf_data = query_conf(conf.hss_yaml_path)
    conf_data['hss']['apn'] = apn
    update_conf(conf_data, conf_file=conf.hss_yaml_path)
    conf_data = query_conf(conf.lte_yaml_path)
    conf_data['smf']['subnet'][0]['dnn'] = apn
    if ims:
        conf_data['smf']['subnet'][1]['dnn'] = ims
    update_conf(conf_data, conf_file=conf.lte_yaml_path)


def get_plmn_id():
    mcc = ''
    mnc = ''
    if not os.path.exists(conf.scscf_path):
        return mcc, mnc
    with open(conf.scscf_path, 'r') as f:
        data_list = f.read().split("\n")
        for line in data_list:
            if line.startswith("Global-Region-MCC"):
                mcc = str(line.split("=")[1]).strip()
            elif line.startswith("Global-Region-MNCS"):
                mnc = str(line.split("=")[1]).strip()
    return mcc, mnc


def set_lte_addr(primaryDNS, secondaryDNS, packetGwIP):
    conf_result = query_conf(conf_file=conf.lte_yaml_path)
    conf_result['smf']['dns'][0] = str(primaryDNS)
    conf_result['smf']['dns'][1] = str(secondaryDNS)
    update_conf(conf_result, conf_file=conf.lte_yaml_path)
    cmd_line = 'route del -net 0.0.0.0'
    os.system(cmd_line)
    cmd_line = 'route add -net 0.0.0.0/0 gw ' + str(packetGwIP)
    os.system(cmd_line)


def set_mode(mode):
    """

    :param mode: 1. 黑名单  2. 白名单 3. 重定向
    :return:
    """
    if str(mode) == '3':
        send_data('SetBlackList ')
        send_data('SetWhiteList ')
        return
    with open(conf.white_black_path, 'w') as f:
        f.write('mode:' + str(mode))
    update_lte_white_black()


def set_mode_new(mode):
    """
    设置黑白名单模式
    :param mode: 1. 黑名单  2. 白名单 3. 重定向
    :return:
    """
    if str(mode) == '3':
        send_data('SetBlackList ')
        send_data('SetWhiteList ')
        return
    with open(conf.white_black_path, 'w') as f:
        f.write('mode:' + str(mode))
    if str(mode) == '1':
        send_data('SetBlackList 460001234567890')
        send_data('SetWhiteList ')
    if str(mode) == '2':
        send_data('SetBlackList ')
        send_data('SetWhiteList 460001234567890')


def set_white_black(list_mode, operate, imsi_list, voice_phone, ki='31313131313131313131313131313131',
                    opc='A5FFFC8C957E23A6875C4740A19065E2'):
    """
    @param list_mode 1-黑名单，2-白名单
    @param operate 1-新增，2-删除
    @param imsi_list imsi 数组
    @param voice_phone 手机号
    @param ki ki
    @param opc opc
    """
    with open(conf.white_black_path, 'r') as f:
        file_data = f.read().strip()
    if file_data:
        white_black_arr = file_data.split('\n')
    else:
        white_black_arr = []
    if len(white_black_arr) > 0:
        current_mode = white_black_arr[0].split(':')[1].strip()
    else:
        current_mode = list_mode
    new_white_black_arr = []
    if len(white_black_arr) > 1:
        new_white_black_arr = white_black_arr[1:]
    # not clear
    if current_mode == list_mode:
        if operate == 1:  # add
            new_white_black_arr.extend(imsi_list)
        if operate == 2:  # delete
            for item in imsi_list:
                new_white_black_arr.remove(item)
    if current_mode != list_mode:
        if operate == 1:
            new_white_black_arr = imsi_list
    white_black_arr = ['mode:' + list_mode]
    new_white_black_arr = list(set(new_white_black_arr))
    white_black_arr.extend(new_white_black_arr)
    with open(conf.white_black_path, 'w') as f:
        f.write('\n'.join(white_black_arr))
    #
    update_user_cfg_for_white_black(operate, imsi_list, voice_phone, ki, opc, current_mode != list_mode)
    update_lte_white_black()
    cmd = "cd " + conf.cli_cmd_path + " && ./epc_cli mme reload_acl"
    logger.info(cmd)
    sts, output = commands.getstatusoutput(cmd)
    logger.info("./epc_cli mme reload_acl -->" + str(sts) + "--" + str(output))


def update_user_cfg_for_white_black(operate, list_info, voice_phone, ki='31313131313131313131313131313131',
                                    opc='A5FFFC8C957E23A6875C4740A19065E2',
                                    clear_data=False):
    """
    :param operate:  1 新增 2 删除
    :param list_info:
    :param voice_phone:
    :param ki:
    :param opc:
    :param clear_data:
    :return:
    """
    if not os.path.exists(conf.user_cfg_path):
        return
    mcc, mnc = get_plmn_id()
    if len(mnc) < 3:
        mnc = mnc.rjust(3, '0')
    with open(conf.user_cfg_path, 'r') as f:
        data_list = f.read().strip().split('\n')
    if clear_data:
        data_list = [data_list[0]]
    data_list_map = dict()
    for item in data_list:
        item_arr = item.split(' ')
        if len(item_arr) > 3:
            data_list_map[item_arr[0]] = item
    new_data_list = None
    if operate == 1:  # 新增
        new_data_list = data_list
        for imsi in list_info:
            if not voice_phone or voice_phone == '0':
                voice_phone_item = '1' + imsi[5:]
            else:
                voice_phone_item = voice_phone
            if imsi in data_list_map:
                new_data_list.remove(data_list_map.get(imsi))
            new_data_list.append(
                "{imsi} {imsi}@ims.mnc{mnc}.mcc{mcc}.3gppnetwork.org sip:{imsi}@ims.mnc{mnc}.mcc{mcc}.3gppnetwork.org {ki} 8000 {opc}:opc {voice_phone}".format(
                    imsi=imsi, voice_phone=voice_phone_item, mcc=mcc, mnc=mnc, ki=ki, opc=opc
                ))
    if operate == 2:  # delete
        new_data_list = [data_list[0]]
        for item in data_list[1:]:
            line_list = item.strip().split(" ")
            if line_list[0].strip() not in list_info:
                new_data_list.append(item)
    with open(conf.user_cfg_path, 'w') as f:
        f.write('\n'.join(new_data_list))


def get_user_cfg_list():
    if not os.path.exists(conf.user_cfg_path):
        return []
    with open(conf.user_cfg_path, 'r') as f:
        data_list = f.read().strip().split('\n')
    if len(data_list) <= 1:
        return []
    result = []
    for line in data_list[1:]:
        if line.strip() == '':
            continue
        line_arr = line.split(" ")
        imsi = line_arr[0].strip()
        ki = line_arr[3].strip()
        opc = line_arr[5].strip().replace(':opc', '')
        voice_phone = line_arr[6].strip()
        result.append({
            'imsi': imsi,
            'ki': ki,
            'opc': opc,
            'voice_phone': voice_phone
        })
    return result


def update_lte_white_black():
    with open(conf.white_black_path, 'r') as f:
        data_list = f.read().strip().split('\n')
    mode = data_list[0].split(':')[1]
    black_list = []
    white_list = []
    if mode == '1':
        black_list = data_list[1:]
    else:
        white_list = data_list[1:]
    send_data('SetBlackList ' + ' '.join(black_list))
    send_data('SetWhiteList ' + ' '.join(white_list))


def query_black_white():
    with open(conf.white_black_path, 'r') as f:
        file_content = f.read().strip()
    data_list = []
    if file_content:
        data_list = file_content.split('\n')
    list_mode = 1
    if len(data_list) > 0:
        list_mode = data_list[0].split(':')[1].strip()
    list_info = []
    if len(data_list) > 1:
        list_info = data_list[1:]
    list_info = [int(item) for item in list_info]
    return {'listmode': list_mode,
            'listinfo': list_info}


def start_sniffer():
    response = send_with_response('StartSniffer', '109', 'StartSniffer')
    result = lte_response.get_item_val(response, 'RESULT')
    return result


def set_netmode(mode):
    """

    :param mode: 1 1-FDD-LTE 2-TDD-LTE
    :return:
    """
    if mode == '1':
        res_data = send_with_response('SwitchNetMode FDD-LTE', '109', 'SwitchNetMode')
        return lte_response.get_item_val(res_data, 'INFO')
    if mode == '2':
        res_data = send_with_response('SwitchNetMode TDD-LTE', '109', 'SwitchNetMode')
        return lte_response.get_item_val(res_data, 'INFO')
    return ''


def set_device(status):
    if status == '1':
        thread.start_new_thread(start_ime_proc, ())
        time.sleep(10)
    elif status == '2':
        stop_device()
    else:
        stop_device()
        thread.start_new_thread(start_ime_proc, ())
        time.sleep(10)


def stop_device():
    output = commands.getoutput('cd /root/ims/bin && /bin/bash ./start_ims.sh stop')
    logger.info(output)
    nrf_pid = commands.getoutput("ps -ef | grep NRF_APP | grep -v grep | awk '{print $2}'")
    if nrf_pid:
        logger.info("NRF pid=" + nrf_pid)
        for pid in nrf_pid.split("\n"):
            os.system("kill -9 " + pid)
    pcf_pid = commands.getoutput("ps -ef | grep PCF_APP | grep -v grep | awk '{print $2}'")
    if pcf_pid:
        logger.info("PCF pid=" + pcf_pid)
        for pid in pcf_pid.split("\n"):
            os.system("kill -9 " + pid)


def is_ims_running():
    output = commands.getoutput('cd /root/ims/bin && /bin/bash ./status_ims.sh')
    logger.info(output)
    return len(output) > 0


def _send_start_code():
    cmd = 'StartCell'
    suc_code = '109'
    rule_msg = 'StartCell'
    logger.info(cmd)
    current_time = int(time.time())
    g_sock.sendto(cmd, (conf.lte_addr, conf.lte_port))
    time.sleep(0.5)
    total_time = 0.0
    while total_time < 50.0:
        status = get_lte_state()
        if status == 1:
            return 'success'
        msg = lte_response.get_msg_by_code_rule_msg(suc_code, rule_msg, current_time)
        if msg:
            return msg
        total_time += 0.2
        time.sleep(0.2)
    raise Exception('lte response timeout')


def __reboot():
    """基站重启"""
    connect_param = {
        'host': conf.REMOTE_HOST,
        'port': 22,
        'username': 'root',
        'pwd': conf.REMOTE_PWD
    }
    ssh_client = ssh_utils.SSHConnection(connect_param)
    ssh_client.connect()
    ssh_client.run_cmd("reboot")
    del ssh_client


def set_power(power):
    response_msg = send_with_response('SetTxPwrLevel ' + str(power), '109', 'SetTxPwrLevel')
    return lte_response.get_item_val(response_msg, 'INFO')


def set_location(tur):
    global location_lock
    logger.info('set location' + str(tur))
    location_lock = tur


def listening():
    global g_sock, lte_sniffer_code, lte_state, is_ready, location_lock
    g_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    g_sock.bind(('0.0.0.0', conf.local_listen_port))
    g_sock.settimeout(20)
    thread.start_new_thread(lte_beat_heart, ())
    while True:
        try:
            data, addr = g_sock.recvfrom(16384)
            # print data
            logger.info(data)
            if not is_ready:
                current_time = str(int(time.time()))
                g_sock.sendto('SetTime ' + current_time, (conf.lte_addr, conf.lte_port))
                is_ready = True
            response = lte_response.set_msg(data)
            # heart
            if response.get('code') == '101':
                lte_state = lte_response.get_heart_status()
            if response.get('code') == '103':
                msg = response.get('msg')
                data_arr = msg.split(' ')
                if len(data_arr) > 1 and data_arr[1] == 'OneUeInfoIndi':
                    taType = ''
                    imsi = ''
                    imei = ''
                    ulSig = ''
                    for item in data_arr:
                        if item.find("imsi") == 0:
                            imsi = lte_response.get_value(item)
                        if item.find("imei") == 0:
                            imei = lte_response.get_value(item)
                        if item.find("taType") == 0:
                            taType = lte_response.get_value(item)
                        if item.find("ulSig") == 0:
                            ulSig = lte_response.get_value(item)
                    if taType == 'TA_REQ' or taType == 'TRIG_ATTACH' or taType == 'ATTACH':
                        send_user_info(imsi, imei)
                    else:
                        logger.info('imsi=' + str(imsi) + ';ulSig=' + ulSig + ";location_lock=" + str(
                            location_lock))
                        if location_lock == 1:
                            send_location_user(imsi, ulSig)
            if response.get('code') == '107':
                msg = response.get('msg')
                data_arr = msg.split(' ')
                if data_arr[1] == 'SnifferRsltIndi':
                    item = ''.join(data_arr[4:])
                    pci = ''
                    rsrp = ''
                    if item.find('erfcn') == -1:
                        earfcn = 1
                    else:
                        sniffer_data = item.split(',')
                        earfcn = lte_response.get_value(sniffer_data[0])
                        pci = lte_response.get_value(sniffer_data[1])
                        rsrp = lte_response.get_value(sniffer_data[2])
                    send_sniffer_info(earfcn, pci, rsrp)
        except Exception as e:
            logger.error(e)


def send_location_user(imsi, ulSig):
    if int(imsi) == 0:
        return
    device_id = ip_utils.get_device_info()
    request_param = {
        'cmdType': 'locationUser',
        'deviceId': device_id,
        'params': {
            'imsi': int(imsi),
            'reSignalPower': int(ulSig),
        }
    }
    http_responser.response_json(request_param)


def send_sniffer_info(earfcn, pci, rsrp):
    device_id = ip_utils.get_device_info()
    sniffer_code = lte_response.get_sniffer_code()
    code = 0
    if sniffer_code == 1:
        code = 1
    request_param = {
        "code": code,
        "cmdType": "sniffer",
        "deviceId": device_id,
        "params": {
            "erfcn": earfcn,
            "pci": pci,
            "rsrp": rsrp,
        }
    }
    http_responser.response_json(request_param)


def send_user_info(imsi, imei):
    if int(imsi) == 0:
        return
    report_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    device_id = ip_utils.get_device_info()
    request_param = {
        'cmdType': 'register',
        'deviceId': device_id,
        'params': {
            'imsi': int(imsi),
            'imei': imei,
            'time': report_time
        }
    }
    http_responser.response_json(request_param)


def get_device_power_status(timeout=None):
    status = power_helper.get_power_status()
    if status == '-1':
        return 2
    if status == '00':
        return 1
    else:
        return 3


def beat_heart():
    while True:
        device_id = ip_utils.get_device_info()
        device_status = get_lte_state()
        # 正在执行重启或关闭操作
        if get_status_rebooting():
            logger.info('device rebooting,device_status=3')
            device_status = 3
        power_status = get_device_power_status(timeout=5)
        data = {
            "cmdType": "heart",
            "deviceId": device_id,
            "params": {
                "ip": conf.heart_ip,
                "deviceStatus": device_status,
                "powerStatus": power_status
            }
        }
        http_responser.response_json(data, url=conf.heart_url)
        time.sleep(10)


def lte_beat_heart():
    while True:
        logger.info('HeatBeat')
        g_sock.sendto('HeatBeat', (conf.lte_addr, conf.lte_port))
        time.sleep(conf.lte_beat_heart_time)


def start_udp():
    thread.start_new_thread(listening, ())
    time.sleep(5)
    # thread.start_new_thread(lte_beat_heart, ())


def start_beat_heart():
    thread.start_new_thread(beat_heart, ())


def start_ime_proc():
    os.system("cd /root/5gc/bin && nohup ./NRF_APP > nrf.log 2>&1 & ")
    os.system("cd /root/5gc/bin && nohup ./PCF_APP > nrf.log 2>&1 & ")
    cmd = 'cd /root/ims/bin && /bin/bash ./start_ims.sh start'
    logger.info(cmd)
    output = commands.getoutput(cmd)
    logger.info(output)


def generate_sms_media_file(req_data):
    """
    生成彩信文件
    """
    upload_path = '/root/sms_file'
    img_name = req_data.get('params', {}).get('fileName', '')
    send_phone = req_data.get('params', {}).get('sendPhone', '')
    if not os.path.exists(os.path.join(upload_path, img_name)):
        return {"_status": 1, "_msg": '彩信文件%s不存在' % img_name}
    suffix = img_name[img_name.rfind('.'):]
    if suffix == '.mp4':
        new_file = 'part000001.mp4'
    elif suffix == '.gif':
        new_file = '76f89e4409d6113a.gif'
    else:
        new_file = '1234' + img_name[img_name.rfind('.'):]
    move_cmd = 'cd {tone_dir} && mv {old_file} {new_file}'.format(tone_dir=upload_path, old_file=img_name,
                                                                  new_file=new_file)
    logger.info(move_cmd)
    os.system(move_cmd)
    cmd = "cd {tone_dir} && ./createMMS {img_name} {send_phone} 18877779999 && rm -rf {tone_dir}/mmse && ln -s {tone_dir}/{img_name}.out {tone_dir}/mmse".format(
        tone_dir=upload_path, img_name=new_file, send_phone=send_phone)
    logger.info(cmd)
    os.system(cmd)
    return {}


def set_mms_addr(req_data):
    """
    彩信地址
    """
    addr = req_data.get('params', {}).get('addr', '')
    port = req_data.get('params', {}).get('port')
    if len(addr) == 0 or not ip_utils.is_valid_ip(addr):
        return {"_status": 1, "_msg": '彩信地址格式错误'}
    if not port:
        return {"_status": 1, "_msg": '彩信端口不能为空'}
    cmd = 'ifconfig ens1:mms %s/24' % addr
    startup_file = '/etc/rc.local'
    with open(startup_file, 'r') as f:
        data = f.read().split("\n")
    new_data = []
    exit_old = False
    for line in data:
        if line.find('ifconfig ens1:mms') >= 0:
            new_data.append(cmd)
            exit_old = True
        else:
            new_data.append(line)
    if not exit_old:
        new_data.append(cmd)
    with open(startup_file, 'w') as f:
        f.write('\n'.join(new_data))
    logger.info(cmd)
    os.system(cmd)
    # 设置端口
    server_path = '/root/sms_file/conf.json'
    origin_conf = {}
    if os.path.exists(server_path):
        with open(server_path, 'r') as f:
            data = f.read()
            if data:
                origin_conf = json.loads(data)
    origin_conf['port'] = port
    with open(server_path, 'w') as f:
        json.dump(origin_conf, f)

    cmd = 'cd /root/sms_file && /bin/bash ./start.sh'
    logger.info(cmd)
    os.system(cmd)
    return {}


def download_tone(req_data):
    url = req_data.get('params', {}).get('URL', '')
    voice_name = req_data.get('params', {}).get('voiceName', '')
    # 1.视频 2. 彩信
    msg_type = req_data.get('params', {}).get('type', '')
    logger.info("begin to download tone from %s" % url)
    download_dir = '/root/tone'
    try:
        # if os.path.exists(download_dir):
        #     shutil.rmtree(download_dir, ignore_errors=True)
        # file_name = z_file.download_and_extract(url, download_dir, 5)
        if not voice_name:
            url_parse_result = urlparse.urlparse(url)
            query_params = url_parse_result.query
            if not query_params:
                raise Exception('url not found param voiceName')
            all_query_params = query_params.split('&')
            for item in all_query_params:
                param_kv = item.split('=')
                if len(param_kv) == 2 and param_kv[0] == 'voiceName':
                    voice_name = param_kv[1]
        if not voice_name:
            raise Exception('url not found param voiceName')
        is_mmse = check_mmse_type(msg_type, voice_name)
        if is_mmse:
            download_dir = '/root/sms_file'
        if voice_name.endswith("zip"):
            z_file.download_and_extract(url, download_dir, 5)
        else:
            z_file.download_http_file(url, download_dir, file_name=voice_name)
        if voice_name.endswith('.mp4') and not is_mmse:
            idx = voice_name.find('.mp4')
            file_name = voice_name[0:idx]
            cmd = 'ffmpeg -i {tone_dir}/{voice_name} -ac 1 -ar 8000 -f amr {tone_dir}/{file_name}.amr.bak ' \
                  '&& /root/ims/bin/AMRConvert {tone_dir}/{file_name}.amr.bak {tone_dir}/{file_name}.amr'.format(
                voice_name=voice_name,
                file_name=file_name,
                tone_dir=download_dir)
            logger.info(cmd)
            os.system(cmd)
        elif voice_name.endswith('.amr'):
            cmd = "mv {tone_dir}/{voice_name} {tone_dir}/{voice_name}.bak && /root/ims/bin/AMRConvert {tone_dir}/{voice_name}.bak {tone_dir}/{voice_name}".format(
                tone_dir=download_dir, voice_name=voice_name)
            logger.info(cmd)
            os.system(cmd)
        elif is_mmse:
            mmse_file_size = os.path.getsize(os.path.join(download_dir, voice_name))
            if mmse_file_size > 1024 * 1024 * 2:
                os.remove(os.path.join(download_dir, voice_name))
                return {"_status": 1, "_msg": '彩信文件大小超限(2M)'}
            logger.info('彩信文件%s下载' % str(voice_name))
        else:
            return {"_status": 1, "_msg": '文件格式错误，只支持mp4/amr/png/jpg/gif'}
    except Exception as e:
        logger.error(log_helper.format_exc_all())
        description = 'download error %s' % str(e)
        return {"_status": 1, "_msg": description}
    return {}


def check_mmse_type(msg_type, voice_name):
    """
    彩信判断
    """
    if voice_name.endswith('.png') or voice_name.endswith('.jpg') or voice_name.endswith('.gif'):
        return True
    if voice_name.endswith('.mp4') and str(msg_type) == '2':
        return True
    return False


def set_sip_account(req_data):
    sip_ip = req_data.get('params', {}).get('sipIp', '')
    sip_port = req_data.get('params', {}).get('sipPort', '')
    user_name = req_data.get('params', {}).get('userName', '')
    pwd = req_data.get('params', {}).get('userPassword', '')
    with open(conf.ims_path, 'r') as f:
        config_data = f.read().strip()
    config_lines = config_data.split('\n')
    new_lines = []
    for line in config_lines:
        if line.startswith('PBX_IP'):
            new_lines.append('PBX_IP:' + sip_ip)
        elif line.startswith('PBX_PORT'):
            new_lines.append('PBX_PORT:' + sip_port)
        elif line.startswith('USER_NAME'):
            new_lines.append('USER_NAME:' + user_name)
        elif line.startswith('USER_PASSWD'):
            new_lines.append('USER_PASSWD:' + pwd)
        else:
            new_lines.append(line)
    with open(conf.ims_path, 'w') as f:
        f.write('\n'.join(new_lines))
    return {}


def query_sip_account():
    with open(conf.ims_path, 'r') as f:
        config_data = f.read().strip()
    config_lines = config_data.split('\n')
    ret = {}
    for line in config_lines:
        if line.startswith('PBX_IP'):
            ret['sipIp'] = line.split(':')[1].strip()
        if line.startswith('PBX_PORT'):
            ret['sipPort'] = line.split(':')[1].strip()
        if line.startswith('USER_NAME'):
            ret['userName'] = line.split(':')[1].strip()
        if line.startswith('USER_PASSWD'):
            ret['userPassword'] = line.split(':')[1].strip()
    return ret


def shutdown():
    t = threading.Timer(1, __local_shutdown)
    t.start()


def __local_shutdown():
    logger.info('开始关机')
    os.system('shutdown -h now')
    logger.info('关机完成')


def set_ip_mode(mode):
    """

    :param mode: 0. ipv4  1. ipv6
    :return:
    """
    cmd_str = 'rm -rf /root/epc && rm -rf /root/ims && rm -rf /root/video_sdp.txt && rm -rf /root/video_sdp_invite.txt && rm -rf /root/audio_sdp.txt && rm -rf /root/video_sdp_update.txt &&'
    if str(mode) == '0':
        cmd_str += 'ln -sf /root/epc-ipv4 /root/epc && ln -sf /root/ims-ipv4 /root/ims && ln -sf /root/audio_sdp.txt-ipv4 /root/audio_sdp.txt && ln -sf /root/video_sdp.txt-ipv4 /root/video_sdp.txt && ln -sf /root/video_sdp_invite.txt-ipv4 /root/video_sdp_invite.txt && ln -sf /root/video_sdp_update.txt-ipv4 /root/video_sdp_update.txt'
    else:
        cmd_str += 'ln -sf /root/epc-ipv6 /root/epc && ln -sf /root/ims-ipv6 /root/ims && ln -sf /root/audio_sdp.txt-ipv6 /root/audio_sdp.txt && ln -sf /root/video_sdp.txt-ipv6 /root/video_sdp.txt && ln -sf /root/video_sdp_invite.txt-ipv6 /root/video_sdp_invite.txt && ln -sf /root/video_sdp_update.txt-ipv6 /root/video_sdp_update.txt'
    logger.info(cmd_str)
    os.system(cmd_str)


def query_ip_mode():
    """
    查询ip模式
    """
    cmd_str = 'ls -l /root/ims |grep ^l'
    output = commands.getoutput(cmd_str)
    logger.info(output)
    if output.find('ipv6') > 0:
        return 1
    return 0


if __name__ == '__main__':
    # start_udp()
    # print start_sniffer()
    # send_data('StopCell')
    # time.sleep(2)
    # print start_sniffer()
    # print set_netmode('1')
    # set_netmode('2')
    # set_arcfn(10663)
    # time.sleep(160)
    # print send_with_response('GetCellPara', '104')
    # set_device('2')
    # time.sleep(20)
    # params = {'plmn': 45400, 'earfcn': 1381, 'tac': 223, 'pci': 956, 'cellid': 398}
    # print send_with_response('SetSib1Para 454 02 228 378', '109', 'SetSib1Para')
    # print set_bts_info(params)
    # time.sleep(10)
    # print send_with_response('Reboot 1', '109', 'Reboot')
    # set_device('1')
    # send_data("GetRfPara")
    # time.sleep(20)
    # start_sniffer()
    # set_white_black('1', 2, ['460012691612822'])
    # set_arcfn(10333)
    # set_power(3)
    # time.sleep(10)
    # print get_rf_param()
    # time.sleep(127000)
    # print query_black_white()
    print query_conf('/Users/guowei/Documents/python_workplace/wl_report_lte-small-box-http/docs/smf.yaml')
